import React, {Component} from 'react'

export default class extends Component{
  constructor() {
    super();
    this.state = {
      code: "",
      pool: "ABCDEFGHJKLMNPQRSTUVWXYZ23456789",
    }
    this.drawCodePicture = this.drawCodePicture.bind(this)
    this.changeCode = this.changeCode.bind(this)
  }

  // 随机数
  randomNum(min, max) {
    return parseInt(Math.random() * (max - min) + min, 10)
  }

  // 随机色
  randomColor(min, max) {
    const r = this.randomNum(min, max)
    const g = this.randomNum(min, max)
    const b = this.randomNum(min, max)
    return `rgb(${r},${g},${b})`
  }

  // 验证码
  drawCodePicture() {
    const ctx = this.refs.verifyCode.getContext('2d')
    // 填充背景色
    ctx.fillStyle = this.randomColor(180, 230)
    ctx.fillRect(0, 0, 85, 30)
    let imgCode = ""
    // 生成随机样式code
    for (let i = 0; i < 4; i++) {
      const text = this.state.pool[this.randomNum(0, this.state.pool.length)]
      imgCode += text
      const fontSize = this.randomNum(16, 24)
      const deg = this.randomNum(-30, 30)
      /*
       * 绘制文字并让四个文字在不同的位置显示的思路 :
       * 1、定义字体
       * 2、定义对齐方式
       * 3、填充不同的颜色
       * 4、保存当前的状态（以防止以上的状态受影响）
       * 5、平移translate()
       * 6、旋转 rotate()
       * 7、填充文字
       * 8、restore出栈
       * */
      ctx.font = `${fontSize}px Simhei`
      ctx.textBaseline = 'top'
      ctx.fillStyle = this.randomColor(80, 150)
      /*
       * save() 方法把当前状态的一份拷贝压入到一个保存图像状态的栈中。
       * 这就允许您临时地改变图像状态，
       * 然后，通过调用 restore() 来恢复以前的值。
       * save是入栈，restore是出栈。
       * 用来保存Canvas的状态。save之后，可以调用Canvas的平移、放缩、旋转、错切、裁剪等操作。 restore：用来恢复Canvas之前保存的状态。防止save后对Canvas执行的操作对后续的绘制有影响。
       *
       * */
      ctx.save()
      ctx.translate(20 * i + 10, 10)
      ctx.rotate(deg * Math.PI / 180)
      // fillText() 方法在画布上绘制填色的文本。文本的默认颜色是黑色。
      // 请使用 font 属性来定义字体和字号，并使用 fillStyle 属性以另一种颜色/渐变来渲染文本。
      // context.fillText(text,x,y,maxWidth);
      ctx.fillText(text, -5, -5)
      ctx.restore()
    }
    // 5.随机产生5条干扰线,干扰线的颜色要浅一点
    for (let i = 0; i < 5; i++) {
      ctx.beginPath()
      ctx.moveTo(this.randomNum(0, 85), this.randomNum(0, 42.5))
      ctx.lineTo(this.randomNum(0, 85), this.randomNum(0, 42.5))
      ctx.strokeStyle = this.randomColor(180, 230)
      ctx.closePath()
      ctx.stroke()
    }
    // 6.随机产生30个干扰的小点
    for (let i = 0; i < 30; i++) {
      ctx.beginPath()
      ctx.arc(this.randomNum(0, 85), this.randomNum(0, 42.5), 1, 0, 1.5 * Math.PI)
      ctx.closePath()
      ctx.fillStyle = this.randomColor(150, 200)
      ctx.fill()
    }
    this.setState({code: imgCode})
    // 当前验证码
    return imgCode
  }

  // 是否为调试环境
  isDev() {
    return process.env.NODE_ENV === 'development'
  }

  changeCode() {
    const currentCode = this.drawCodePicture()
    if (this.isDev()) {
      const {setInputCode} = this.props
      if (setInputCode) {
        setInputCode(currentCode)
      }
    }
  }

  componentDidMount() {
    this.changeCode()
  }

  render() {
    return (
      <canvas
        ref='verifyCode'
        width={85}
        height={30}
        onClick={this.changeCode}
      />
    )
  }
}
